﻿using DayuCode.Designer.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace DayuCode.Designer.Model
{
    public class QHttpClient
    {
        private static HttpClient httpClient;

        public static HttpClient HttpClient
        {
            get
            {
                if (httpClient == null)
                {
                    HttpClientHandler httpClientHandler = new HttpClientHandler
                    {
                        AllowAutoRedirect = true,
                        UseCookies = true,
                        CookieContainer = new CookieContainer()
                    };

                    httpClient = new HttpClient(httpClientHandler);
                }
                return httpClient;
            }
        }

        private static JsonSerializerSettings serializerSettings = new JsonSerializerSettings
        {
            // 设置为驼峰命名
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        public static T Post<T>(string url, object parameters)
        {
            string respText = PostString(url, parameters);
            if (!string.IsNullOrEmpty(respText) && !respText.Contains("\"hasError\""))
            {
                T obj = JsonConvert.DeserializeObject<T>(respText);

                return obj;
            }
            else throw new Exception(respText);
        }

        public static void Execute(string url, object parameters)
        {
            PostString(url, parameters);
        }

        public static IList<T> PostList<T>(string url, object parameters)
        {
            string respText = PostString(url, parameters);
            if (!string.IsNullOrEmpty(respText) && !respText.Contains("\"hasError\""))
            {
                IList<T> list = JsonConvert.DeserializeObject<List<T>>(respText);
                return list;
            }
            else throw new Exception(respText);
        }

        public static T Get<T>(string url)
        {
            string respText = GetString(url);

            if (!string.IsNullOrEmpty(respText) && !respText.Contains("\"hasError\""))
            {
                T obj = JsonConvert.DeserializeObject<T>(respText);

                return obj;
            }
            else throw new Exception(respText);
        }

        public static IList<T> GetList<T>(string url)
        {
            string respText = GetString(url);

            if (!string.IsNullOrEmpty(respText) && !respText.Contains("\"hasError\""))
            {
                IList<T> list = JsonConvert.DeserializeObject<List<T>>(respText);

                return list;
            }
            else throw new Exception(respText);
        }

        public static string PostString(string url, object parameters)
        {
            string requestBody = "";
            if (parameters != null)
            {
                foreach (System.Reflection.PropertyInfo property in parameters.GetType().GetProperties())
                {
                    string pname = property.Name;
                    object value = property.GetValue(parameters, null);
                    string strVal = "";
                    if (value != null)
                    {
                        strVal = JsonConvert.SerializeObject(value, serializerSettings);
                    }
                    pname = HttpUtility.UrlEncode(pname, Encoding.UTF8);
                    strVal = HttpUtility.UrlEncode(strVal, Encoding.UTF8);
                    requestBody += string.Format("&{0}={1}", pname, strVal);
                }
            }
            if (requestBody.Length > 0)
            {
                requestBody = requestBody.Substring(1);
            }
            Task<HttpResponseMessage> responseTask = null;
            string respText = null;
            try
            {
                string fullUrl = url;
                if (!fullUrl.Contains(":"))
                {
                    fullUrl = AppInstance.ApiServer + url;
                }
                var data = new StringContent(requestBody, Encoding.UTF8, "application/x-www-form-urlencoded");
                responseTask = HttpClient.PostAsync(fullUrl, data); 
                responseTask.Wait();
                var response = responseTask.Result;
                bool err = false;
                if (response.IsSuccessStatusCode)
                {
                    respText = response.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    err = true;
                    respText = response.Content.ReadAsStringAsync().Result;

                }
                if (err || (respText != null && respText.Contains("\"hasError\"") && respText.Contains("\"errMsg\"")))
                {
                    var errmsg = JsonConvert.DeserializeObject<Dictionary<string, string>>(respText);
                    throw new HException(errmsg["errMsg"]);
                }

                responseTask.Dispose();
                responseTask = null;
            }
            catch (Exception ex)
            {
                string errmsg = ex.ToString();
                if (errmsg.Length > 800) errmsg = errmsg.Substring(0, 800);
                throw new HException("后台服务报错：\r\n\r\n" + errmsg);
            }
            finally
            {
                HttpClient.CancelPendingRequests();
                if (responseTask != null)
                {
                    responseTask.Dispose();
                }
            }
            if (respText != null && respText.Contains("\"hasError\"") && respText.Contains("\"errMsg\""))
            {
                var errmsg = JsonConvert.DeserializeObject<Dictionary<string, string>>(respText);
                throw new HException(errmsg["errMsg"]);
            }
            
            return respText;
        }

        public static string GetString(string url)
        {
            string fullUrl = AppInstance.ApiServer + url;
            Task<HttpResponseMessage> responseTask = HttpClient.GetAsync(fullUrl);
            responseTask.Wait();
            var response = responseTask.Result;
            if (response.IsSuccessStatusCode)
            {
                string respText = response.Content.ReadAsStringAsync().Result;
                if (respText.Contains("\"hasError\"") && respText.Contains("\"errMessage\""))
                {
                    //throw new Exception(respText);
                    var errmsg = JsonConvert.DeserializeObject<Dictionary<string, string>>(respText);
                    throw new Exception(errmsg["errorMessage"]);
                }
                return respText;
            }
            else
            {
                return null;
            }
        }

        public static T UploadFile<T>(string uploadUrl, string fullFileName)
        {
            var content = new MultipartFormDataContent();
            //添加字符串参数，参数名为qq
            //content.Add(new StringContent("123456"), "qq");
            FileInfo fileInfo = new FileInfo(fullFileName);
            //添加文件参数，参数名为files，文件名为123.png

            //content.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(fullFileName)), "file", fileInfo.Name);//File.ReadAllBytes不能读取已经打开的文件
            using (FileStream fs = new FileStream(fullFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                var buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                fs.Close();
                content.Add(new ByteArrayContent(buffer), "file", fileInfo.Name);
            }


            var requestUri = uploadUrl;
            var respText = HttpClient.PostAsync(requestUri, content).Result.Content.ReadAsStringAsync().Result;
            if (respText.Contains("\"hasError\"") && respText.Contains("\"errMessage\""))
            {
                //throw new Exception(respText);
                var errmsg = JsonConvert.DeserializeObject<Dictionary<string, string>>(respText);
                throw new Exception(errmsg["errorMessage"]);
            }
            T obj = JsonConvert.DeserializeObject<T>(respText);
            return obj;
        }
    }
}
